unit SQLitePages;

interface

uses
  Windows, RzTabs, ComCtrls, Classes, SysUtils, Controls, DBCtrls, DB, 
  StdCtrls, ExtCtrls, frmEditBlob, Forms, RaDBOLE, SynEditor,
  SynEdit, OleCtrls, SHDocVw, cxEdit,
  cxDBData, cxGridCustomTableView, cxGridTableView,
  cxGridDBTableView, cxGridLevel, cxGridCustomView,
  cxGrid, Provider, DBClient, RaGSQLite;

type
  TPageTableStructure = class(TRzTabSheet)
  public
    lvTable: TListView;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

  TPageTableData = class(TRzTabSheet)
  private
    FConnection:   TRaSQLiteDB;
    // FZconnection: TZConnection;
    FTableName:    string;
    FCurrentField: string;
    Blob:          TRaDBOLE;
    procedure SetTableName(const Value: string);
  protected
    procedure TblAfterScroll(DataSet: TDataSet);
    procedure cdsAfterPost(DataSet: TDataSet);
    procedure cdsAfterDelete(DataSet: TDataSet);
    procedure btnEditClick(Sender: TObject);
    procedure cgvwCellClick(Sender: TcxCustomGridTableView; ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton;
      AShift: TShiftState; var AHandled: boolean);
    procedure dbnvBeforeAction(Sender: TObject; Button: TNavigateBtn);
  public
    dbnvTbl: TDBNavigator;
    // gdTbl:       TDBGrid;
    gdTbl:   TCxGrid;
    cgvw:    TcxGridDBTableView;
    cglv:    TcxGridLevel;
    // tblData:     TZTable;
    tblData: TRaSQLiteTable;

    dspData: TDataSetProvider;
    cdsData: TClientDataSet;

    dsData:      TDataSource;
    pnl:         TPanel;
    lblCnt:      TLabel;
    lblField:    TLabel;
    edtRecCount: TEdit;
    btnEdit:     TButton;
    constructor Create(AOwner: TComponent); override;
    procedure CreateWnd; override;
    destructor Destroy; override;
  public
    property Connection: TRaSQLiteDB Read FConnection Write FConnection;
    property TableName: string Read FTableName Write SetTableName;
  end;

  TPageSQLWindow = class(TRzTabSheet)
  private
    FConnection:  TRaSQLiteDB;
    // FZConnection: TZConnection;
    procedure SetConnection(const Value: TRaSQLiteDB);
  protected
    procedure mmSQLChange(Sender: TObject);
    procedure mmSQLKeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
    procedure mmSQLMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
    procedure mmSQLReplaceText(Sender: TObject; const ASearch, AReplace: string; Line, Column: integer; var Action: TSynReplaceAction);
  public
    mmSQL:    TSynEditor;
    spl:      TSplitter;
    ppResult: TRzPageControl;
    // gdResult: TDBGrid;
    gdResult: TcxGrid;
    cgvw:     TcxGridDBTableView;
    cglv:     TcxGridLevel;
    mmResult: TMemo;
    dsData:   TDataSource;
    // qryData:  TZQuery;
    qryData: TRaSQLiteQuery;

    dspData: TDataSetProvider;
    cdsData: TClientDataSet;

    constructor Create(AOwner: TComponent); override;
    procedure CreateWnd; override;
    destructor Destroy; override;
  public
    property Connection: TRaSQLiteDB Read FConnection Write SetConnection;
  end;

  TPageWelcome = class(TRzTabSheet)
  public
    WB: TWebBrowser;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;


implementation

uses
  frmMain;

{ TPageTableStructure }

constructor TPageTableStructure.Create(AOwner: TComponent);
var
  column: TListColumn;
begin
  inherited Create(AOwner);
  lvTable           := TListView.Create(Self);
  lvTable.Parent    := Self;
  lvTable.Align     := alClient;
  column            := lvTable.Columns.Add;
  column.Caption    := formmain.siLang.GetText('sFieldName');   // 'Field Name';
  column.Width      := 100;
  column            := lvTable.Columns.Add;
  column.Caption    := FormMain.siLang.GetText('sDataType');    // 'Data Type';
  column.Width      := 100;
  column            := lvTable.Columns.Add;
  column.Caption    := FormMain.siLang.GetText('sIndex');       // 'Index';
  column.Width      := 100;
  column            := lvTable.Columns.Add;
  column.Caption    := FormMain.siLang.GetText('sDefault');     // 'Default';
  column.Width      := 100;
  lvTable.ViewStyle := vsReport;
end;

destructor TPageTableStructure.Destroy;
begin
  lvTable.Free;
  inherited Destroy;
end;

{ TPageTableData }

constructor TPageTableData.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  // self.Width  := 534;
  // self.Height := 338;

  dbnvTbl              := TDBNavigator.Create(Self);
  dbnvTbl.Parent       := Self;
  dbnvTbl.Align        := alTop;
  dbnvTbl.Height       := 25;
  // dbnvTbl.OnClick      := dbnvClick;
  dbnvtbl.BeforeAction := dbnvBeforeAction;

  pnl            := TPanel.Create(Self);
  pnl.Parent     := Self;
  pnl.Align      := alBottom;
  pnl.Height     := 41;
  pnl.Caption    := EmptyStr;
  pnl.BevelOuter := bvNone;

  {
  gdTbl        := TDBGrid.Create(Self);
  gdTbl.Parent := self;
  gdTbl.Align  := alClient;
  gdTbl.OnCellClick := gdTblCellClick;
  }

  lblCnt          := TLabel.Create(pnl);
  lblCnt.Parent   := pnl;
  lblCnt.AutoSize := False;
  lblCnt.Width    := 77;
  lblCnt.Height   := 13;
  lblCnt.Left     := 13;
  lblCnt.Top      := 14;
  lblCnt.Caption  := FormMain.siLang.GetText('sRecordCount');  //  'Record Count: ';

  lblField          := TLabel.Create(pnl);
  lblField.Parent   := pnl;
  lblField.AutoSize := False;
  lblField.Width    := 157;
  lblField.Height   := 13;
  lblField.Left     := TRzPageControl(AOwner).Width - 285;
  lblField.Top      := 14;
  lblField.Caption  := FormMain.siLang.GetText('sCurrentField');  // 'Current Field: ';
  // lblField.Anchors  := [akTop, akRight];

  edtRecCount         := TEdit.Create(pnl);
  edtRecCount.Parent  := pnl;
  edtRecCount.Width   := 73;
  edtRecCount.Height  := 21;
  edtRecCount.Enabled := False;
  edtRecCount.Left    := 96;
  edtRecCount.Top     := 13;
  edtRecCount.Text    := EmptyStr;

  btnEdit         := TButton.Create(pnl);
  btnEdit.Parent  := pnl;
  btnEdit.Width   := 107;
  btnEdit.Height  := 25;
  btnEdit.Left    := TRzPageControl(AOwner).Width - 122;
  btnEdit.Top     := 9;
  btnEdit.Caption := FormMain.siLang.GetText('sEditBlob2');  // 'Edit Blob';
  btnEdit.OnClick := btnEditClick;
  // btnEdit.Anchors := [akTop, akRight];

  // FZconnection := TZConnection.Create(nil);
  // FZconnection.Protocol := 'sqlite-3';

  // tblData := TZTable.Create(nil);
  tblData             := TRaSQLiteTable.Create(nil);
  // tblData.Connection := FZconnection;
  tblData.AfterScroll := TblAfterScroll;

  dspData              := TDataSetProvider.Create(self);
  dspData.Name         := '__dsp';
  dspData.DataSet      := tblData;
  cdsData              := TClientDataSet.Create(self);
  cdsData.ProviderName := '__dsp';
  cdsData.AfterPost := cdsAfterPost;
  cdsData.AfterDelete := cdsAfterDelete;

  dsData               := TDataSource.Create(nil);
  Blob := TRaDBOLE.Create(nil);
  // connect controls
  // gdTbl.DataSource   := dsData;
  dbnvTbl.DataSource := dsData;
  dsData.DataSet     := cdsData;
  Blob.DataSet       := dsData;

end;

procedure TPageTableData.CreateWnd;
var
  i: integer;
begin
  inherited CreateWnd;

  gdTbl              := TcxGrid.Create(self);
  gdTbl.Parent       := self;
  gdTbl.Align        := alClient;
  cglv               := gdTbl.Levels.Add;
  cgvw               := TcxGridDBTableView(gdTbl.CreateView(TcxGridDBTableView));
  cglv.Control       := gdTbl;
  cglv.GridView      := cgvw;
  gdTbl.ParentWindow := self.Handle;

  cgvw.OptionsView.NoDataToDisplayInfoText := EmptyStr;

  cgvw.OptionsView.GroupByBox      := False;
  cgvw.OptionsView.ColumnAutoWidth := True;
  // cgvw.OptionsView.ShowEditButtons

  cgvw.OptionsCustomize.ColumnFiltering := False;
  cgvw.OptionsCustomize.ColumnGrouping  := False;
  cgvw.OptionsCustomize.ColumnMoving    := False;

  cgvw.OptionsData.DeletingConfirmation := False;

  cgvw.DataController.DataSource := dsData;

  cgvw.OptionsData.Editing := not FormMain.Config.DataReadonly;
  
  (cgvw.DataController as IcxCustomGridDataController).DeleteAllItems;
  cgvw.DataController.CreateAllItems;

  for i := 0 to cgvw.ColumnCount - 1 do
    cgvw.Columns[i].Options.ShowEditButtons := isebNever;

  cgvw.OnCellClick := cgvwCellClick;
end;

procedure TPageTableData.dbnvBeforeAction(Sender: TObject; Button: TNavigateBtn);
begin
  if Button = nbRefresh then
  begin
    if cdsData.State in [dsInsert, dsEdit] then
      dbnvTbl.BtnClick(nbPost);
  end;
end;

destructor TPageTableData.Destroy;
begin
  dbnvTbl.Free;
  gdTbl.Free;
  tblData.Free;
  dsData.Free;
  pnl.Free;

  // FZconnection.Disconnect;
  // FZconnection.Free;
  inherited Destroy;
end;

procedure TPageTableData.SetTableName(const Value: string);
begin
  //FZconnection.Database := FConnection.Database;
  //FZconnection.Connect;
  // tblData.Connection := FConnection;
  FTableName := Value;
  tblData.Close;
  // tblData.Connection := FZConnection;
  tblData.Connection := FConnection;
  tblData.TableName  := FTableName;
  tblData.Open;
  cdsData.Open;
  TblAfterScroll(tblData);

  dbnvTbl.Enabled := not FormMain.Config.DataReadonly;
  btnEdit.Enabled := not FormMain.Config.DataReadonly;
end;

procedure TPageTableData.TblAfterScroll(DataSet: TDataSet);
begin
  if cdsData.Active then
    edtRecCount.Text := IntToStr(cdsData.RecordCount)
  else
    edtRecCount.Text := '0';
end;

procedure TPageTableData.btnEditClick(Sender: TObject);
begin
  if FCurrentField = EmptyStr then
    Exit;
  if cdsData.FieldByName(FCurrentField).DataType = ftBlob then
  begin
    //  edit blob
    Blob.DataField := FCurrentField;
    with TFormEditBlob.Create(Application, Blob) do
    begin
      Caption := FormMain.siLang.GetText('sEditBlob') + FCurrentField;  //  'Edit Blob - ' + FCurrentField;
      if ShowModal = mrOk then
      begin
        if leFile.Text = '(NULL)' then
          Blob.SaveToDatabase(EmptyStr)
        else if leFile.Text <> '(BLOB)' then
          blob.SaveToDatabase(leFile.Text);
      end;
      Free;
    end;
  end;

end;

procedure TPageTableData.cdsAfterDelete(DataSet: TDataSet);
begin
  if cdsData.ChangeCount > 0 then
    try
      cdsData.ApplyUpdates(0);
    except
      MessageBox(FormMain.Handle, PChar(formmain.siLang.GetText('sLogicError')), PChar(FormMain.siLang.GetText('sError')), MB_OK or MB_ICONERROR);
      cdsData.CancelUpdates;
    end;
end;

procedure TPageTableData.cdsAfterPost(DataSet: TDataSet);
begin
  if cdsData.ChangeCount > 0 then
    try
      cdsData.ApplyUpdates(0);
    except
      MessageBox(FormMain.Handle, PChar(formmain.siLang.GetText('sLogicError')), PChar(FormMain.siLang.GetText('sError')), MB_OK or MB_ICONERROR);
      cdsData.CancelUpdates;
    end;
end;

procedure TPageTableData.cgvwCellClick(Sender: TcxCustomGridTableView; ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton;
  AShift: TShiftState; var AHandled: boolean);
begin
  if not cdsData.Active then
    Exit;

  lblField.Caption := Format(FormMain.siLang.GetText('sFmtCurrentField'), [ACellViewInfo.Item.Caption]);
  FCurrentField    := ACellViewInfo.Item.Caption;
end;

{ TPageSQLWindow }

constructor TPageSQLWindow.Create(AOwner: TComponent);

begin
  inherited Create(AOwner);

  ppResult        := TRzPageControl.Create(Self);
  ppResult.Parent := Self;
  ppResult.Align  := alBottom;
  ppResult.Height := 166;

  spl        := TSplitter.Create(Self);
  spl.Parent := Self;
  spl.Align  := alBottom;
  spl.Top    := 0;

  mmSQL                    := TSynEditor.Create(self);
  mmSQL.Parent             := Self;
  mmSQL.Align              := alClient;
  mmSQL.ActiveLine.Visible := False;
  if FormMain.Config.UseSqliteSyntax then
    mmSQL.Highlighter := FormMain.SynSqlite
  else
    mmSQL.Highlighter := FormMain.SQL;
  mmSQL.Options := [eoAutoIndent, eoDragDropEditing, eoEnhanceEndKey, eoGroupUndo, eoShowScrollHint, eoTabsToSpaces, eoColumnEditExtension];
  mmSQL.PopupMenu         := FormMain.pmEdit;
  mmSQL.RightEdge.Visible := False;
  mmSQL.WordWrap.Enabled  := FormMain.Config.WordWrap;
  mmSQL.WantTabs := True;

  mmSQL.OnChange      := mmSQLChange;
  mmSQL.OnClick       := mmSQLChange;
  mmSQL.OnKeyUp       := mmSQLKeyUp;
  mmSQL.OnMouseUp     := mmSQLMouseUp;
  mmSQL.OnReplaceText := mmSQLReplaceText;

  //FZConnection          := TZConnection.Create(nil);
  //FZConnection.Protocol := 'sqlite-3';
  qryData               := TRaSQLiteQuery.Create(nil);


  dspData:= TDataSetProvider.Create(self);
  dspData.DataSet := qryData;
  dspData.Name := '__dsp';
  cdsData:= TClientDataSet.Create(self);
  cdsData.ProviderName := '__dsp';

  dsData                := TDataSource.Create(nil);
  dsData.DataSet        := cdsData;

end;

procedure TPageSQLWindow.CreateWnd;
var
  ts1, ts2: TRzTabSheet;
  i:        integer;
begin
  inherited CreateWnd;
  ts1             := TRzTabSheet.Create(ppResult);
  ts1.PageControl := ppResult;
  ts1.Caption     := FormMain.siLang.GetText('sResultData');  // 'Result Data';

  ts2             := TRzTabSheet.Create(ppResult);
  ts2.PageControl := ppResult;
  ts2.Caption     := FormMain.siLang.GetText('sSQLInformation');  //  'Information';

  mmResult            := TMemo.Create(ts2);
  mmResult.Parent     := ts2;
  mmResult.Align      := alClient;
  mmResult.ReadOnly   := True;
  mmResult.ScrollBars := ssVertical;

  ppResult.ActivePageIndex := 0;

  // cxgrid
  gdResult              := TcxGrid.Create(self);
  gdResult.Parent       := ts1;
  gdResult.Align        := alClient;
  cglv                  := gdResult.Levels.Add;
  cgvw                  := TcxGridDBTableView(gdResult.CreateView(TcxGridDBTableView));
  cglv.Control          := gdResult;
  cglv.GridView         := cgvw;
  gdResult.ParentWindow := self.Handle;

  cgvw.OptionsView.NoDataToDisplayInfoText := EmptyStr;

  cgvw.OptionsView.GroupByBox      := False;
  cgvw.OptionsView.ColumnAutoWidth := True;

  cgvw.OptionsCustomize.ColumnFiltering := False;
  cgvw.OptionsCustomize.ColumnGrouping  := False;
  cgvw.OptionsCustomize.ColumnMoving    := False;

  cgvw.OptionsData.DeletingConfirmation := False;

  cgvw.DataController.DataSource := dsData;

  cgvw.OptionsData.Editing := False;

  (cgvw.DataController as IcxCustomGridDataController).DeleteAllItems;
  cgvw.DataController.CreateAllItems;

  for i := 0 to cgvw.ColumnCount - 1 do
    cgvw.Columns[i].Options.ShowEditButtons := isebNever;
end;

destructor TPageSQLWindow.Destroy;
begin
  mmSQL.Free;
  spl.Free;
  ppResult.Free;
  dsData.Free;
  qryData.Free;
  //FZConnection.Free;
  inherited Destroy;
end;

procedure TPageSQLWindow.mmSQLChange(Sender: TObject);
begin
  FormMain.ShowPOSInfo(mmSQL.Lines.Count, mmSQL.CaretX, mmSQL.CaretY);
end;

procedure TPageSQLWindow.mmSQLKeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
begin
  FormMain.ShowPOSInfo(mmSQL.Lines.Count, mmSQL.CaretX, mmSQL.CaretY);
end;

procedure TPageSQLWindow.mmSQLMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
  FormMain.ShowPOSInfo(mmSQL.Lines.Count, mmSQL.CaretX, mmSQL.CaretY);
end;

procedure TPageSQLWindow.mmSQLReplaceText(Sender: TObject; const ASearch, AReplace: string; Line, Column: integer; var Action: TSynReplaceAction);
begin
  FormMain.ShowPOSInfo(mmSQL.Lines.Count, mmSQL.CaretX, mmSQL.CaretY);
end;

procedure TPageSQLWindow.SetConnection(const Value: TRaSQLiteDB);
begin
  FConnection := Value;
  qryData.Connection    := FConnection;
  //FZConnection.Disconnect;
  //FZConnection.Database := FConnection.Database;
  //FZConnection.Connect;
end;

{ TPageWelcome }

constructor TPageWelcome.Create(AOwner: TComponent);
var
  fn: string;
begin
  inherited Create(AOwner);
  WB                     := TWebBrowser.Create(Self);
  TWinControl(WB).Parent := Self;
  WB.Align               := alClient;
  Caption                := FormMain.siLang.GetText('sWelcome');  // 'Welcome!';
  // : show a welcome page
  fn                     := EmptyStr;
  case FormMain.Config.Language of
    1: fn := ExtractFilePath(ParamStr(0)) + 'Help\Welcome_EN.html';
    2: fn := ExtractFilePath(ParamStr(0)) + 'Help\Welcome.html';
  end;

  if FileExists(fn) then
    wb.Navigate(fn);
end;

destructor TPageWelcome.Destroy;
begin
  WB.Free;
  inherited Destroy;
end;

end.
